﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Shower : MonoBehaviour
{
    public GameObject RawImages;
    public GameObject Fliters;
    public GameObject AfterFliters;
    public GameObject AfterDowns;
    public GameObject Ws;
    public GameObject Evidences;
    public Font thefont;

    int _ImageSize;
    int _FliterCount;
    int _numberCount;
    int _imageCount;
    private int _fliterSize;
    int _afterDownSampleSize;

    private RawImage[,,] fliterImgs;
    private RawImage[,,] afterfliterImgs;
    private RawImage[,,] afterdownsampleImgs;

    private RawImage[,,] wsImages;
    private Text[,] evidencetexts;
    // Use this for initialization
    void Start ()
    {
		
	}
	
	// Update is called once per frame
	void Update ()
    {
		
	}

    public void InitSize(int numberCount,int ImageCount, int ImageSize, int fliterSize,int fliterCount,int AfterDownSampleSize)
    {
        _ImageSize = ImageSize;
        _numberCount = numberCount;
        _FliterCount = fliterCount;
        _fliterSize = fliterSize;
        _afterDownSampleSize = AfterDownSampleSize;
        _imageCount = ImageCount;
        for (int i = 0;i < ImageCount;i++)
        {
            GameObject rawImage = new GameObject("RawImage" + i.ToString());
            rawImage.transform.SetParent(RawImages.transform,false);
            var theimage = rawImage.AddComponent<UnityEngine.UI.RawImage>();
            var rt = theimage.GetComponent<RectTransform>();
            rt.sizeDelta = new Vector2(ImageSize * 2, ImageSize * 2);
            theimage.texture = new Texture2D(ImageSize , ImageSize);
        }
        //每个Image 对应显示一组fliter;
        fliterImgs = new RawImage[ImageCount,numberCount, fliterCount];
        for (int intimage = 0; intimage < ImageCount; intimage++)
        {
            GameObject OneImageRoot = new GameObject("OneImage" + intimage.ToString());
            OneImageRoot.transform.SetParent(Fliters.transform, false);
            GridLayoutGroup hgroup = OneImageRoot.AddComponent<GridLayoutGroup>();

            hgroup.cellSize = new Vector2(56.0f,56.0f);
            hgroup.spacing = new Vector2(10.0f,10.0f);
            hgroup.constraint = GridLayoutGroup.Constraint.FixedColumnCount;
            hgroup.constraintCount = fliterCount;
            var csf = OneImageRoot.AddComponent<ContentSizeFitter>();
            csf.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
            for (int i = 0; i < numberCount; i++)
            {
                for (int j = 0; j < fliterCount; j++)
                {
                    GameObject fliterImage = new GameObject("fliter" + i.ToString() + "_" + j.ToString());
                    fliterImage.transform.SetParent(OneImageRoot.transform, false);
                    var theimage = fliterImage.AddComponent<UnityEngine.UI.RawImage>();
                    var rt = theimage.GetComponent<RectTransform>();
                    rt.sizeDelta = new Vector2(fliterSize * 5, fliterSize * 5);
                    theimage.texture = new Texture2D(fliterSize, fliterSize);
                    fliterImgs[intimage,i, j] = theimage;
                }
            }
        }


        afterfliterImgs = new RawImage[ImageCount,numberCount, fliterCount];
        for (int i = 0; i < ImageCount ; i++)
        {
            GameObject OneImageRoot = new GameObject("OneImage" + i.ToString());
            OneImageRoot.transform.SetParent(AfterFliters.transform, false);
            GridLayoutGroup hgroup = OneImageRoot.AddComponent<GridLayoutGroup>();
            hgroup.cellSize = new Vector2(56.0f, 56.0f);
            hgroup.spacing = new Vector2(10.0f, 10.0f);
            hgroup.constraint = GridLayoutGroup.Constraint.FixedColumnCount;
            hgroup.constraintCount = fliterCount;

            var csf = OneImageRoot.AddComponent<ContentSizeFitter>();
            csf.verticalFit = ContentSizeFitter.FitMode.PreferredSize;

            for (int j = 0; j < numberCount; j++)
            {
                for(int k = 0 ; k < fliterCount;k++)
                {
                    GameObject afterfliterImage = new GameObject("afterfliter" + i.ToString() + "_" + j.ToString());
                    afterfliterImage.transform.SetParent(OneImageRoot.transform, false);
                    var theimage = afterfliterImage.AddComponent<UnityEngine.UI.RawImage>();
                    var rt = theimage.GetComponent<RectTransform>();
                    rt.sizeDelta = new Vector2(ImageSize * 2, ImageSize * 2);
                    theimage.texture = new Texture2D(ImageSize, ImageSize);
                    afterfliterImgs[i, j,k] = theimage;
                }
            }
        }

        afterdownsampleImgs = new RawImage[ImageCount,numberCount, fliterCount];
        for (int i = 0; i < ImageCount; i++)
        {
            GameObject OneImageRoot = new GameObject("OneImage" + i.ToString());
            OneImageRoot.transform.SetParent(AfterDowns.transform, false);
            GridLayoutGroup hgroup = OneImageRoot.AddComponent<GridLayoutGroup>();
            hgroup.cellSize = new Vector2(56.0f, 56.0f);
            hgroup.spacing = new Vector2(10.0f, 10.0f);
            hgroup.constraint = GridLayoutGroup.Constraint.FixedColumnCount;
            hgroup.constraintCount = fliterCount;

            var csf = OneImageRoot.AddComponent<ContentSizeFitter>();
            csf.verticalFit = ContentSizeFitter.FitMode.PreferredSize;

            for (int j = 0; j < numberCount; j++)
            {
                for(int k = 0 ; k < fliterCount;k++)
                {
                    GameObject afterdownImage = new GameObject("afterdown" + i.ToString() + "_" + j.ToString());
                    afterdownImage.transform.SetParent(OneImageRoot.transform, false);
                    var theimage = afterdownImage.AddComponent<UnityEngine.UI.RawImage>();
                    var rt = theimage.GetComponent<RectTransform>();
                    rt.sizeDelta = new Vector2(AfterDownSampleSize * 2, AfterDownSampleSize * 2);
                    theimage.texture = new Texture2D(AfterDownSampleSize, AfterDownSampleSize);
                    afterdownsampleImgs[i, j,k] = theimage;
                }
            }
        }
        wsImages = new RawImage[ImageCount,numberCount, fliterCount];
        for (int intimage = 0; intimage < ImageCount; intimage++)
        {
            GameObject OneImageRoot = new GameObject("OneImage" + intimage.ToString());
            OneImageRoot.transform.SetParent(Ws.transform, false);
            GridLayoutGroup hgroup = OneImageRoot.AddComponent<GridLayoutGroup>();
            hgroup.cellSize = new Vector2(56.0f, 56.0f);
            hgroup.spacing = new Vector2(10.0f, 10.0f);
            hgroup.constraint = GridLayoutGroup.Constraint.FixedColumnCount;
            hgroup.constraintCount = fliterCount;

            var csf = OneImageRoot.AddComponent<ContentSizeFitter>();
            csf.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
            for (int i = 0; i < numberCount; i++)
            {
                for (int j = 0; j < fliterCount; j++)
                {
                    GameObject wImage = new GameObject("w" + i.ToString() + "_" + j.ToString());
                    wImage.transform.SetParent(OneImageRoot.transform, false);
                    var theimage = wImage.AddComponent<UnityEngine.UI.RawImage>();
                    var rt = theimage.GetComponent<RectTransform>();
                    rt.sizeDelta = new Vector2(AfterDownSampleSize * 4, AfterDownSampleSize * 4);
                    theimage.texture = new Texture2D(AfterDownSampleSize, AfterDownSampleSize);
                    wsImages[intimage,i, j] = theimage;
                }
            }
        }



        evidencetexts = new UnityEngine.UI.Text[ImageCount,numberCount];
        for (int i = 0; i < ImageCount; i++)
        {
            GameObject OneImageRoot = new GameObject("OneImage" + i.ToString());
            OneImageRoot.transform.SetParent(Evidences.transform, false);
            GridLayoutGroup hgroup = OneImageRoot.AddComponent<GridLayoutGroup>();
            hgroup.cellSize = new Vector2(150.0f, 56.0f);
            hgroup.spacing = new Vector2(10.0f, 10.0f);

            var csf = OneImageRoot.AddComponent<ContentSizeFitter>();
            csf.verticalFit = ContentSizeFitter.FitMode.PreferredSize;

            for (int j = 0; j < numberCount; j++)
            {
                GameObject eviText = new GameObject("evidences" + i.ToString() + "_" + j.ToString());
                eviText.transform.SetParent(OneImageRoot.transform, false);
                UnityEngine.UI.Text t = eviText.AddComponent<UnityEngine.UI.Text>();
                evidencetexts[i, j] = t;
                t.fontSize = 20;
                t.font = thefont;
            }
        }
    }


    public void SetRawImage(float[,] datas, int width)
    {
        for (int i = 0; i < datas.GetLength(0) && i < RawImages.transform.childCount; i++)
        {
            Texture2D t = RawImages.transform.GetChild(i).GetComponent<UnityEngine.UI.RawImage>().texture as Texture2D;
            for (int j = 0; j < _ImageSize; j++)
            {
                for (int k = 0; k < _ImageSize; k++)
                {
                    float aaaaaa = datas[i, (j + 1) * width + k + 1] * 0.01f;
                    Color c = new Color(aaaaaa, aaaaaa, 0.0f);
                    t.SetPixel(k, _ImageSize - 1 - j, c);
                }
            }
            t.Apply();
        }
    }

    public void SetFliters(float[,,,] filters)
    {
        for (int ic = 0; ic < _imageCount;ic++ )
        {
            for (int i = 0; i < _numberCount; i++)
            {
                for (int j = 0; j < _FliterCount; j++)
                {
                    Texture2D t = fliterImgs[ic,i, j].texture as Texture2D;
                    for (int k = 0; k < _fliterSize; k++)
                    {
                        for (int m = 0; m < _fliterSize; m++)
                        {
                            Color c = new Color(filters[i, j, k, m], filters[i, j, k, m], 0.0f);
                            t.SetPixel(k, m, c);
                        }
                    }
                    t.Apply();
                }
            }
        }
    }

    public void SetAfterFliter(float[, , ,,] afterflilters)
    {
        for (int i = 0; i < _imageCount ; i++)
        {
            for (int j = 0; j < _numberCount; j++)
            {
                for (int k = 0; k < _FliterCount; k++)
                {
                    Texture2D t = afterfliterImgs[i, j,k].texture as Texture2D;
                    for (int l = 0; l < _ImageSize; l++)
                    {
                        for (int m = 0; m < _ImageSize; m++)
                        {
                            Color c = new Color(afterflilters[i, j, k,l, m], afterflilters[i, j, k,l, m], 0.0f);
                            t.SetPixel(m, _ImageSize - 1 - l, c);
                        }
                    }
                    t.Apply();
                }
            }
        }
    }

    public void SetAfterDownSample(float[,,,,] afterDownSample)
    {
        for (int i = 0; i < _imageCount ; i++)
        {
            for (int j = 0; j < _numberCount; j++)
            {
                for (int k = 0; k < _FliterCount; k++)
                {
                    Texture2D t = afterdownsampleImgs[i, j,k].texture as Texture2D;
                    for (int l = 0; l < _afterDownSampleSize; l++)
                    {
                        for (int m = 0; m < _afterDownSampleSize; m++)
                        {
                            Color c = new Color(afterDownSample[i, j, k,l, m], afterDownSample[i, j, k,l, m], 0.0f);
                            t.SetPixel(m, _afterDownSampleSize - 1 - l, c);
                        }
                    }
                    t.Apply();
                }
            }

        }
    }

    public void SetW(float[,,,] ws)
    {

        float maxw = 0.0f;
        for (int i = 0; i < 10; i++)
        {
            for (int j = 0; j < 14; j++)
            {
                for (int m = 0; m < 14; m++)
                {
                    if (Math.Abs(ws[i, 0, j, m]) > maxw)
                    {
                        maxw = Math.Abs(ws[i, 0, j, m]);
                    }
                }
            }
        }

        float d = 1.0f / maxw * 0.95f;

        for (int ic = 0; ic < _imageCount;ic++ )
        {
            for (int j = 0; j < _numberCount; j++)
            {
                for (int k = 0; k < _FliterCount; k++)
                {
                    Texture2D t = wsImages[ic,j, k].texture as Texture2D;
                    for (int l = 0; l < _afterDownSampleSize; l++)
                    {
                        for (int m = 0; m < _afterDownSampleSize; m++)
                        {
                            float temp = ws[j, k, l, m];
                            Color c = new Color(temp < 0.0f ? (-temp * d) : 0.0f, temp > 0.0f ? (temp * d) : 0.0f, 0);
                            t.SetPixel(m, _afterDownSampleSize - 1 - l, c);
                        }
                    }
                    t.Apply();
                }
            }
        }
    }

    public void SetE(float[,] e)
    {
        for (int i = 0; i < _imageCount; i++)
        {
            double[] Evidence = new double[_numberCount];

            for (int j = 0; j < _numberCount; j++)
            {
                Evidence[j] = e[j, i];
            }

            double totalsoftmax = 0.0f;
            for (int j = 0; j < _numberCount; j++)
            {
                totalsoftmax += Math.Pow(Math.E, Evidence[j]);
            }

            double[] softmax = new double[_numberCount];
            for (int j = 0; j < _numberCount; j++)
            {
                softmax[j] = Math.Pow(Math.E, Evidence[j]) / totalsoftmax;
                string softv = "";
                if (softmax[j] < 0.0001)
                {
                    softv = "0%";
                }
                else
                {
                    softv = (((int) (softmax[j] * 10000) / 100.0f)).ToString() + "%";
                }
                evidencetexts[i, j].text = "是  " + j.ToString() + "  " + softv;
            }
        }



    }
}
